package com.example.api.mall.controller;

import com.example.api.mall.logic.ITestLogic;
import com.example.common.core.annotation.NoLoginAuth;
import com.example.common.core.exception.LinkerException;
import com.example.common.core.exception.SystemException;
import com.example.common.core.result.Result;
import com.example.entity.domain.user.User;
import com.example.entity.api.mall.test.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/test")
@CrossOrigin
//浏览器在正式请求之前会先执行一个简单请求，其中包含是否允许访问，
//跨域原理是多了两个头: Access-Control-Request-Method Access-Control-Request-Header
//也可以手动注入一个CorsFilter类，其中配置允许的请求方式，请求来源等其他条件
@NoLoginAuth
public class TestController {

    //注入方式获取HttpServletRequest
    @Autowired
    private HttpServletRequest request;

    //注入方式获取HttpServletResponse
    @Autowired
    private HttpServletResponse response;

    //注入方式获取ServletContext
    @Autowired
    private ServletContext servletContext;

    //注入方式获取ApplicationContext
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ITestLogic testLogic;

    /**
     * 直接ApplicationContext获取容器中的Bean
     * //TODO 还需要测试
     * @return
     */
    @RequestMapping("/getBean")
    public Result<Object> getBean(){
        return Result.success(applicationContext.getBean(ITestLogic.class));
    }

    /**
     * 测试无需登录注释是否有效
     * @param request
     * @return
     */
    @RequestMapping("/noLoginAuth")
    public Result<UserVo> noLoginAuth(HttpServletRequest request){
        UserVo user = testLogic.test();
        return Result.success(user);
    }



    /**
     * @PathVariable获取路径上的参数
     * @return
     */
    @RequestMapping("/param/{id}")
    public Result<Long> param(@PathVariable("id") Long id){
        return Result.success(id);
    }

    /**
     * 直接获取GET参数，get请求的参数是指用?id=123连接在url上，pathinfo模式不可以
     * @return
     */
    @RequestMapping("/param1")
    public Result<Long> param1(Long id){
        return Result.success(id);
    }

    /**
     * 从HttpServletRequest中获取参数
     * @return
     */
    @RequestMapping("/param2")
    public Result<Long> param2(HttpServletRequest request){
        return Result.success(Long.valueOf(request.getParameter("id")));
    }

    /**
     * @RequestBody说明前端以非表单形式执行POST请求，不加也可以获取
     * @return
     */
    @RequestMapping("/param3")
    @ModelAttribute  //TODO 需要研究
    public Result<User> param3(@RequestBody User user){
        return Result.success(user);
    }

    /**
     * 如果不适用token，如何操作session，
     * @param request
     * @return
     */
    @RequestMapping("/session")
    public Result<Integer> session(HttpServletRequest request){
        //除了直接注入，也可以使用其他方式获取
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request1 = servletRequestAttributes.getRequest();
        HttpServletResponse response1 = servletRequestAttributes.getResponse();
        //也可以使用@Autowired注入

        //获取session
        HttpSession session = request.getSession();
        Integer loginflag = (Integer) session.getAttribute("login_flag");
        return Result.success(loginflag);
    }

    /**
     * 获取各种上下文
     * @return
     */
    @RequestMapping("/applicationContext")
    public Result<Integer> context(){
        //TODO
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        ServletContext servletContext = servletRequestAttributes.getRequest().getServletContext();//获取servlet上下文
//        servletContext.getRealPath();
        return Result.success(1);
    }

    /**
     * 测试业务异常
     * @return
     */
    @RequestMapping("/linkerException")
    public Result<UserVo> linkerException(){
        throw new LinkerException("这里是LinkerException测试");
    }

    /**
     * 测试系统异常
     * @return
     */
    @RequestMapping("/systemException")
    public Result<UserVo> systemException(){
        throw new SystemException("这里是SystemException测试");
    }
}
